import 'dart:math';
import 'package:fftea/fftea.dart';

class FFTUtil{

  static List<int> fft(List<int> data) {
    List<double> myData = [];
    for(var i = 0;i<1024;i++){
      myData.add(data[i].toDouble());
    }


    final fft = FFT(myData.length);
    final freq = fft.realFft(myData);

    //freq.discardConjugates().magnitudes();
    List<double> list = [];
    for(var a  in freq){
      list.add(a.x);
      list.add(a.y);
    }
    while(list.length > freq.length+10){
      list.removeLast();
    }


    // 计算频谱
    List<double> spectrum = [];
    for (int i = 0; i <= myData.length / 2; i++) {
      spectrum.add(sqrt(list[2 * i] * list[2 * i] + list[2 * i + 1] * list[2 * i + 1]));
    }

    List<int> spectrumAsBytes = convertToByte(spectrum);
    return  castFft(spectrumAsBytes);
  }



  static List<int> convertToByte(List<double> spectrum) {
    List<int> result = List<int>.filled(spectrum.length, 0);

    // 寻找最大值以便进行归一化
    double maxMagnitude = double.negativeInfinity;
    for (double magnitude in spectrum) {
      if (magnitude > maxMagnitude) {
        maxMagnitude = magnitude;
      }
    }

    // 防止除以零的情况
    if (maxMagnitude == 0) {
      maxMagnitude = 1;
    }

    // 归一化并转换为字节
    for (int i = 0; i < spectrum.length; i++) {
      // 归一化到0-1之间
      double normalized = spectrum[i] / maxMagnitude;
      // 映射到0-255
      result[i] = (normalized * 255).toInt();
    }

    return result;
  }

  static List<int> castFft(List<int> fft) {
    // 得到频谱数据
    List<int> spectrum = List<int>.filled(fft.length ~/ 2, 0);

    // 转换为幅度
    for (int i = 0; i < spectrum.length; i++) {
      double magnitude = sqrt(fft[2 * i]*fft[2 * i]+ fft[2 * i + 1]*fft[2 * i + 1]);
      if (magnitude < 0) {
        spectrum[i] = 0;
      } else if (magnitude > 127) {
        spectrum[i] = 127;
      } else {
        spectrum[i] = magnitude.toInt();
      }
    }

    // 截取前48个元素
    List<int> tmp = spectrum;
    List<int> list = tmp.sublist(0, 48);

    // 将截取后的列表转换为字节数组
    List<int> fft2 = list;

    return fft2;
  }
}